package com.plugin.sproutcore.lang;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.ui.console.MessageConsoleStream;

import com.plugin.sproutcore.util.ConsoleUtil;
import com.plugin.sproutcore.util.ProjectUtil;

/**
 * Call a SproutCore builder, independent of the system.
 * 
 * @author Michael Pugliese
 *
 */
public class SproutCoreProcess 
{
	/**
	 * 
	 * @param command
	 * The command and its parameters you want to run.
	 * @param dir
	 * Directory where you want to run the process.
	 * @param monitor
	 * Monitor the progress of the process.
	 * 
	 * @return
	 * the exit value of the process. By convention, 0 indicates normal termination. 
	 * 
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public static int execute(final List<String> command, final File dir, 
			final IProgressMonitor monitor)
	throws IOException, InterruptedException, CoreException
	{
		ProcessBuilder builder = ProcessFactory.generate(command, dir);
		
		final Process process = builder.start();

		monitorStream(process.getErrorStream(), monitor);
		monitorStream(process.getInputStream(), monitor);
		
		return process.waitFor();
	} 
	
	private static void monitorStream(final InputStream is, 
			final IProgressMonitor monitor) 
	throws InterruptedException, CoreException, IOException
	{
		final InputStreamReader isr = new InputStreamReader(is);
		final BufferedReader br = new BufferedReader(isr);
		String line=null;
		StringBuilder errorStack = new StringBuilder();
		MessageConsoleStream consoleStream = ConsoleUtil.getConsole().newMessageStream();
		while ( (line = br.readLine()) != null)
		{
			if (line != null && line.trim().length() != 0) {
				line = line.trim();
				validate(line, errorStack);
				monitor.setTaskName(line);
				consoleStream.println(line);
			}
		}
		consoleStream.close();
		if (errorStack.length() > 0) {
			IStatus s = ProjectUtil.createErrorStatus(errorStack.toString());
			throw new CoreException(s);
		}
	}
	
	private static void validate(String line, StringBuilder errorStack) 
	{
		// Only throw fatal errors
		if (line.startsWith("WARN"))
		{
			errorStack.append(line);
		}
		else
		if (line.startsWith("FATAL"))
		{
			errorStack.append(line);
		}
	}
	
}
